home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 December: Technology Seed / ATS Dec. '97.toast / Navigation Services SDK 1.0b1 / Examples / Sampler / Sampler ƒ / menus.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-11-20  |  22.3 KB  |  877 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        menus.c
  3.  
  4.     Copyright:    © 1997 by Apple Computer, Inc., all rights reserved.
  5.  
  6. */
  7.  
  8. #pragma segment AppSeg
  9.  
  10. #ifndef __SCRAP__
  11. #include <Scrap.h>
  12. #endif
  13.  
  14. #ifndef __DEVICES__
  15. #include <Devices.h>
  16. #endif
  17.  
  18. #ifndef __TOOLUTILS__
  19. #include <ToolUtils.h>
  20. #endif
  21.  
  22.  
  23. #ifndef Common_Defs
  24. #include "Common.h"
  25. #endif
  26.  
  27. extern Document* gDocumentList[kMaxDocumentCount];
  28. extern short    gDocumentCount;
  29. extern short    gCanUndoDrag;
  30. extern short    gQuit, gQuitting;
  31. extern Boolean    gNavServicesExists;
  32.  
  33. // prototypes:
  34. void SetItemEnable( MenuHandle theMenu, short theItem, short enable );
  35. short DoPaste( );
  36. void DoAbout( );
  37. void DoSelectDictionary( );
  38. void DoSelectDirectory( );
  39. void DoSelectObject( );
  40. void DoSelectVolume( );
  41. void DoCreateFolder( );
  42. void DoCustomOpen( );
  43.  
  44. // for customization:
  45. pascal void myCustomEventProc( NavEventCallbackMessage callBackSelector, NavCBRecPtr callBackParms, NavCallBackUserData callBackUD);
  46. void HandleCustomMouseDown( NavCBRecPtr callBackParms );
  47. void HandleCommandPopup( ControlHandle thePopup, NavCBRecPtr callBackParms );
  48.  
  49.  
  50. // custom dialog item:
  51. #define kControlListID    132
  52. #define kPopupCommand     1
  53.  
  54. // the requested dimensions for our customization area:
  55. #define kCustomWidth    100
  56. #define kCustomHeight    40
  57.                 
  58. // customization globals:
  59. Handle         gDitlList;
  60. MenuHandle     gPopupMenu;
  61. short         gLastTryWidth;
  62. short         gLastTryHeight;
  63.  
  64.                         
  65. // *****************************************************************************
  66. // *
  67. // *    SetItemEnable()
  68. // *
  69. // *****************************************************************************
  70. void SetItemEnable(MenuHandle theMenu, short theItem, short enable)
  71. {
  72.     if (enable)
  73.         EnableItem(theMenu,theItem);
  74.     else
  75.         DisableItem(theMenu,theItem);
  76. }
  77.  
  78.  
  79. // *****************************************************************************
  80. // *
  81. // *    AdjustMenus()
  82. // *
  83. // *****************************************************************************
  84. void AdjustMenus()
  85. {    
  86.     MenuHandle    theMenu;
  87.     Document*    theDocument;
  88.     short        teSelection = 0;
  89.     Str255        theStr;
  90.  
  91.     theDocument = IsDocumentWindow((WindowPtr)FrontWindow());
  92.     
  93.     if (theDocument->theTE != NULL)
  94.         teSelection = (theDocument) && ((**(theDocument->theTE)).selStart != (**(theDocument->theTE)).selEnd);
  95.  
  96.     theMenu = GetMenuHandle(idFileMenu);
  97.  
  98.     SetItemEnable(theMenu,NewItem,gDocumentCount < kMaxDocumentCount);
  99.     SetItemEnable(theMenu,OpenItem,gDocumentCount < kMaxDocumentCount);
  100.  
  101.     SetItemEnable(theMenu,CloseItem,theDocument != 0L);
  102.     SetItemEnable(theMenu,SaveItem,(theDocument) && (theDocument->dirty));
  103.     SetItemEnable(theMenu,RevertItem,(theDocument) && (theDocument->dirty) && (theDocument->fRefNum));
  104.     SetItemEnable(theMenu,SaveACopyItem,theDocument != 0L);
  105.     SetItemEnable(theMenu,DictionaryItem,gNavServicesExists);
  106.  
  107.     theMenu = GetMenuHandle(idEditMenu);
  108.  
  109.     GetIndString(theStr,MenuStringsID,gCanUndoDrag);
  110.     SetMenuItemText(theMenu,iUndo,theStr);
  111.     SetItemEnable(theMenu,iUndo,gCanUndoDrag != slCantUndo);
  112.  
  113.     SetItemEnable(theMenu,iCut,teSelection);
  114.     SetItemEnable(theMenu,iCopy,teSelection);
  115.     SetItemEnable(theMenu,iPaste,theDocument != 0L);
  116.     SetItemEnable(theMenu,iClear,teSelection);
  117.     SetItemEnable(theMenu,iSelectAll,theDocument != 0L);
  118.  
  119.     theMenu = GetMenuHandle(idUtilsMenu);
  120.     SetItemEnable(theMenu,iSelectDir,gNavServicesExists);
  121.     SetItemEnable(theMenu,iSelectVol,gNavServicesExists);
  122.     SetItemEnable(theMenu,iSelectObject,gNavServicesExists);
  123.     SetItemEnable(theMenu,iCreateFolder,gNavServicesExists);
  124.     SetItemEnable(theMenu,iCustomOpen,gNavServicesExists);
  125. }
  126.  
  127.  
  128. // *****************************************************************************
  129. // *
  130. // *    DoPaste()
  131. // *
  132. // *****************************************************************************
  133. short DoPaste()
  134. {    
  135.     long    size, offset;
  136.     Handle    theData;
  137.  
  138.     size = GetScrap(0L,'UPRC',&offset);
  139.  
  140.     if (size <= 0)
  141.         return(0);
  142.  
  143.     theData = NewHandle(size);
  144.     GetScrap(theData,'UPRC',&offset);
  145.  
  146.     HLock(theData);
  147.     PutScrap(size,'test',*theData);
  148.  
  149.     HUnlock(theData);
  150.     DisposeHandle(theData);
  151.  
  152.     return noErr;
  153. }
  154.  
  155.  
  156. // *****************************************************************************
  157. // *
  158. // *    DoSelectDictionary()
  159. // *    
  160. // *****************************************************************************
  161. void DoSelectDictionary()
  162. {    
  163.     NavReplyRecord        theReply;
  164.     NavDialogOptions    dialogOptions;
  165.     OSErr                theErr = noErr;
  166.     NavEventUPP            eventUPP = NewNavEventProc(myEventProc);
  167.     NavTypeListHandle    openList = NULL;
  168.     
  169.     // use the default location for the dialog:
  170.     theErr = NavGetDefaultDialogOptions(&dialogOptions);
  171.  
  172.     GetIndString(dialogOptions.message,rAppStringsID,sChooseFile);
  173.  
  174.     dialogOptions.preferenceKey = kSelectFilePrefKey;
  175.     
  176.     openList = (NavTypeListHandle)GetResource(kOpenRsrcType,kOpenRsrcID);
  177.     if ((openList != NULL)&&(ResError() == noErr))
  178.         HLock((Handle)openList);
  179.         
  180.     theErr = NavChooseFile(    NULL,
  181.                             &theReply,
  182.                             &dialogOptions,
  183.                             eventUPP,
  184.                             NULL,
  185.                             NULL,
  186.                             openList,
  187.                             (NavCallBackUserData)&gDocumentList);
  188.     
  189.     DisposeRoutineDescriptor(eventUPP);
  190.     
  191.     if ((theReply.validRecord)&&(theErr == noErr))
  192.         {
  193.         // grab the target FSSpec from the AEDesc:    
  194.         FSSpec    finalFSSpec;    
  195.         AEDesc     resultDesc;
  196.  
  197.         theErr = AECoerceDesc(&(theReply.selection),typeFSS,&resultDesc);
  198.         if (theErr == noErr)
  199.             {
  200.             BlockMove(*resultDesc.dataHandle,(void*)&finalFSSpec,sizeof(FSSpec));    
  201.             // 'finalFSSpec' is the chosen file…
  202.             }
  203.             
  204.         theErr = NavDisposeReply(&theReply);
  205.         }
  206.     
  207.     HUnlock((Handle)openList);
  208.     DisposeHandle((Handle)openList);
  209. }
  210.  
  211.  
  212. // *****************************************************************************
  213. // *
  214. // *    DoSelectDirectory()
  215. // *    
  216. // *****************************************************************************
  217. void DoSelectDirectory()
  218. {    
  219.     NavReplyRecord        theReply;
  220.     NavDialogOptions    dialogOptions;
  221.     OSErr                theErr = noErr;
  222.     NavEventUPP            eventUPP = NewNavEventProc(myEventProc);
  223.     
  224.     theErr = NavGetDefaultDialogOptions(&dialogOptions);
  225.     
  226.     GetIndString(dialogOptions.message,rAppStringsID,sChooseFolder);
  227.     
  228.     dialogOptions.preferenceKey = kSelectFolderPrefKey;
  229.     
  230.     theErr = NavChooseFolder(    NULL,
  231.                                 &theReply,
  232.                                 &dialogOptions,
  233.                                 eventUPP,
  234.                                 NULL,
  235.                                 (NavCallBackUserData)&gDocumentList);
  236.     
  237.     DisposeRoutineDescriptor(eventUPP);
  238.  
  239.     if ((theReply.validRecord)&&(theErr == noErr))
  240.         {
  241.         // grab the target FSSpec from the AEDesc:    
  242.         FSSpec    finalFSSpec;    
  243.         AEDesc     resultDesc;
  244.  
  245.         theErr = AECoerceDesc(&(theReply.selection),typeFSS,&resultDesc);
  246.         if (theErr == noErr)
  247.             {
  248.             BlockMove(*resultDesc.dataHandle,(void*)&finalFSSpec,sizeof(FSSpec));    
  249.             // 'finalFSSpec' is the selected directory…
  250.             }
  251.         
  252.         theErr = NavDisposeReply(&theReply);
  253.         }
  254. }
  255.  
  256.  
  257. // *****************************************************************************
  258. // *
  259. // *    DoSelectObject()
  260. // *    
  261. // *****************************************************************************
  262. void DoSelectObject()
  263. {    
  264.     NavReplyRecord        theReply;
  265.     NavDialogOptions    dialogOptions;
  266.     OSErr                theErr = noErr;
  267.     NavEventUPP            eventUPP = NewNavEventProc(myEventProc);
  268.     
  269.     theErr = NavGetDefaultDialogOptions(&dialogOptions);
  270.     
  271.     GetIndString(dialogOptions.message,rAppStringsID,sChooseObject);
  272.     
  273.     dialogOptions.preferenceKey = kSelectObjectPrefKey;
  274.     
  275.     theErr = NavChooseObject(    NULL,
  276.                                 &theReply,
  277.                                 &dialogOptions,
  278.                                 eventUPP,
  279.                                 NULL,
  280.                                 (NavCallBackUserData)&gDocumentList);
  281.     
  282.     DisposeRoutineDescriptor(eventUPP);
  283.  
  284.     if ((theReply.validRecord)&&(theErr == noErr))
  285.         {
  286.         // grab the target FSSpec from the AEDesc:    
  287.         FSSpec    finalFSSpec;    
  288.         AEDesc     resultDesc;
  289.  
  290.         theErr = AECoerceDesc(&(theReply.selection),typeFSS,&resultDesc);
  291.         if (theErr == noErr)
  292.             {
  293.             BlockMove(*resultDesc.dataHandle,(void*)&finalFSSpec,sizeof(FSSpec));    
  294.             // 'finalFSSpec' is the selected directory…
  295.             }
  296.         
  297.         theErr = NavDisposeReply(&theReply);
  298.         }
  299. }
  300.  
  301.  
  302.  
  303. // *****************************************************************************
  304. // *
  305. // *    DoSelectVolume()
  306. // *    
  307. // *****************************************************************************
  308. void DoSelectVolume()
  309. {    
  310.     NavReplyRecord        theReply;
  311.     NavDialogOptions    dialogOptions;
  312.     OSErr                theErr = noErr;
  313.     NavEventUPP            eventUPP = NewNavEventProc(myEventProc);
  314.     
  315.     // use the default location for the dialog:
  316.     theErr = NavGetDefaultDialogOptions(&dialogOptions);
  317.     
  318.     GetIndString(dialogOptions.message,rAppStringsID,sChooseVolume);
  319.  
  320.     dialogOptions.preferenceKey = kSelectVolumePrefKey;
  321.     
  322.     theErr = NavChooseVolume(    NULL,
  323.                                 &theReply,
  324.                                 &dialogOptions,
  325.                                 eventUPP,
  326.                                 NULL,
  327.                                 (NavCallBackUserData)&gDocumentList);
  328.     if ((theReply.validRecord)&&(theErr == noErr))
  329.         {
  330.         // grab the target FSSpec from the AEDesc:    
  331.         FSSpec    finalFSSpec;    
  332.         AEDesc     resultDesc;
  333.  
  334.         // there is only one selection here we get only the first AEDesc:
  335.         theErr = AECoerceDesc(&(theReply.selection),typeFSS,&resultDesc);
  336.         if (theErr == noErr)
  337.             {
  338.             BlockMove(*resultDesc.dataHandle,(void*)&finalFSSpec,sizeof(FSSpec));
  339.             // 'finalFSSpec' is the chosen volume…
  340.             }
  341.         
  342.         theErr = NavDisposeReply(&theReply);
  343.         }
  344.         
  345.     DisposeRoutineDescriptor(eventUPP);
  346. }
  347.  
  348.  
  349. // *****************************************************************************
  350. // *
  351. // *    DoCreateFolder()
  352. // *    
  353. // *****************************************************************************
  354. void DoCreateFolder()
  355. {    
  356.     NavReplyRecord        theReply;
  357.     NavDialogOptions    dialogOptions;
  358.     OSErr                theErr = noErr;
  359.     NavEventUPP            eventUPP = NewNavEventProc(myEventProc);
  360.     
  361.     // use the default location for the dialog:
  362.     theErr = NavGetDefaultDialogOptions(&dialogOptions);
  363.     
  364.     GetIndString(dialogOptions.message,rAppStringsID,sCreateFolder);
  365.  
  366.     dialogOptions.preferenceKey = kNewFolderPrefKey;
  367.     
  368.     theErr = NavNewFolder(    NULL,
  369.                             &theReply,
  370.                             &dialogOptions,
  371.                             eventUPP, 
  372.                             (NavCallBackUserData)&gDocumentList);
  373.     if (theReply.validRecord)
  374.         {
  375.         // grab the target FSSpec from the AEDesc:    
  376.         FSSpec    finalFSSpec;    
  377.         AEDesc     resultDesc;
  378.  
  379.         // there is only one selection here so we get the first AEDesc:
  380.         theErr = AECoerceDesc(&(theReply.selection),typeFSS,&resultDesc);
  381.         if (theErr == noErr)
  382.             {
  383.             BlockMove(*resultDesc.dataHandle,(void*)&finalFSSpec,sizeof(FSSpec));
  384.             // 'finalFSSpec' is the newly created folder…
  385.             }
  386.  
  387.         theErr = NavDisposeReply(&theReply);
  388.         }
  389. }
  390.  
  391.  
  392. // *****************************************************************************
  393. // *
  394. // *    HandleCommandPopup()
  395. // *    
  396. // *****************************************************************************
  397. void HandleCommandPopup(ControlHandle thePopup, NavCBRecPtr callBackParms)
  398. {
  399.     OSErr     theErr = noErr;
  400.     short     selection = 0;
  401.     
  402.     selection = GetControlValue(thePopup)-1;
  403.     switch (selection)
  404.         {                                
  405.         case kNavCtlShowDesktop:
  406.         case kNavCtlScrollHome:
  407.         case kNavCtlScrollEnd:
  408.         case kNavCtlPageUp:
  409.         case kNavCtlPageDown:
  410.             theErr = NavCustomControl(callBackParms->context,selection,NULL);
  411.             break;
  412.         
  413.         case kNavCtlShowSelection:
  414.             theErr = NavCustomControl(callBackParms->context,kNavCtlShowSelection,NULL);
  415.             break;
  416.         
  417.         case kNavCtlOpenSelection:
  418.             {
  419.             AEDesc itemToOpen;
  420.             theErr = NavCustomControl(callBackParms->context,kNavCtlOpenSelection,&itemToOpen);
  421.             if (itemToOpen.descriptorType == typeFSS)
  422.                 {    
  423.                 // you may open the file as described by 'itemToOpen', or do whatever you want with it:
  424.                 AEDisposeDesc(&itemToOpen);
  425.                 }
  426.             break;
  427.             }
  428.             
  429.         case kNavCtlCancel:
  430.             theErr = NavCustomControl(callBackParms->context,kNavCtlCancel,NULL);
  431.             break;
  432.     
  433.         case kNavCtlAccept:
  434.             theErr = NavCustomControl(callBackParms->context,kNavCtlAccept,NULL);
  435.             break;
  436.         }
  437. }
  438.  
  439.  
  440. void HandleCustomMouseDown(NavCBRecPtr callBackParms)
  441. {
  442.     OSErr            theErr = noErr;
  443.     ControlHandle    whichControl;                
  444.     Point             where = callBackParms->eventData.event->where;    
  445.     short            theItem = 0;    
  446.     UInt16             firstItem = 0;
  447.     short            realItem = 0;
  448.     short            partCode = 0;
  449.         
  450.     GlobalToLocal(&where);
  451.     theItem = FindDialogItem(callBackParms->window,where);    // get the item number of the control
  452.     partCode = FindControl(where,callBackParms->window,&whichControl);    // get the control itself
  453.     
  454.     // ask NavServices for the first custom control's ID:
  455.     if (callBackParms->context != 0)    // always check to see if the context is correct
  456.         {
  457.         theErr = NavCustomControl(callBackParms->context,kNavCtlGetFirstControlID,&firstItem);    
  458.         realItem = theItem - firstItem + 1;        // map it to our DITL constants:    
  459.         }
  460.                 
  461.     if (realItem == kPopupCommand)
  462.         HandleCommandPopup(whichControl,callBackParms);
  463. }                    
  464.  
  465.  
  466. // *****************************************************************************
  467. // *
  468. // *    myEventProc()    
  469. // *
  470. // *****************************************************************************
  471. pascal void myCustomEventProc(    NavEventCallbackMessage callBackSelector, 
  472.                                 NavCBRecPtr callBackParms, 
  473.                                 NavCallBackUserData callBackUD)
  474. {
  475.     OSErr        theErr = noErr;
  476.     WindowPtr    pWindow = NULL;
  477.     Document**    docList;
  478.     Document*    theDoc = NULL;
  479.     short         index = 0;
  480.  
  481.     if (callBackUD != 0)
  482.         switch (callBackSelector)
  483.             {
  484.             case kNavCBEvent:
  485.                 {
  486.                 docList = (Document**)callBackUD;
  487.                 if (docList != NULL)
  488.                     switch (callBackParms->eventData.event->what)
  489.                         {
  490.                         case mouseDown:
  491.                             HandleCustomMouseDown(callBackParms);
  492.                             break;
  493.                         
  494.                         case updateEvt:
  495.                             pWindow = (WindowPtr)callBackParms->eventData.event->message;
  496.                             theDoc = docList[index];
  497.                             if (theDoc != NULL)
  498.                                 {
  499.                                 while ((theDoc->theWindow != pWindow) && (docList[index] != NULL))
  500.                                     {
  501.                                     index++;
  502.                                     theDoc = docList[index];
  503.                                     }
  504.                                 theDoc = docList[index];
  505.                                 if (theDoc != NULL)
  506.                                     UpdateWindow(theDoc);
  507.                                 }
  508.                             break;
  509.  
  510.                         default:
  511.                             break;
  512.                         }
  513.                 break;
  514.                 }
  515.     
  516.             case kNavCBCustomize:
  517.                 {                                
  518.                 // here are the desired dimensions for our custom area:
  519.                 short neededWidth = callBackParms->customRect.left + kCustomWidth;
  520.                 short neededHeight = callBackParms->customRect.top + kCustomHeight;
  521.                 
  522.                 // check to see if this is the first round of negotiations:
  523.                 if ((callBackParms->customRect.right == 0) && (callBackParms->customRect.bottom == 0))
  524.                     {
  525.                     // it is, so tell NavServices what dimensions we want:
  526.                     callBackParms->customRect.right = neededWidth;
  527.                     callBackParms->customRect.bottom = neededHeight;
  528.                     }
  529.                 else
  530.                     {
  531.                     // we are in the middle of negotiating:
  532.                     if (gLastTryWidth != callBackParms->customRect.right)
  533.                         if (callBackParms->customRect.right < neededWidth)    // is NavServices width too small for us?
  534.                             callBackParms->customRect.right = neededWidth;
  535.  
  536.                     if (gLastTryHeight != callBackParms->customRect.bottom)    // is NavServices height too small for us?
  537.                         if (callBackParms->customRect.bottom < neededHeight)
  538.                             callBackParms->customRect.bottom = neededHeight;
  539.                     }
  540.                 
  541.                 // remember our last size so the next time we can re-negotiate:
  542.                 gLastTryWidth = callBackParms->customRect.right;
  543.                 gLastTryHeight = callBackParms->customRect.bottom;    
  544.                 break;
  545.                 }
  546.                 
  547.             case kNavCBStart:
  548.                 {
  549.                 short    itemType;
  550.                 Rect    itemRect;
  551.                 Handle    itemH;
  552.                 UInt16     firstItem = 0;    
  553.                 short    realItem = 0;
  554.                 
  555.                 // add the rest of the custom controls via the DITL resource list:
  556.                 gDitlList = GetResource('DITL',kControlListID);
  557.                 if ((gDitlList != NULL)&&(ResError() == noErr))
  558.                     if ((theErr = NavCustomControl(callBackParms->context,kNavCtlAddControlList,gDitlList)) == noErr)
  559.                         {
  560.                         theErr = NavCustomControl(callBackParms->context,kNavCtlGetFirstControlID,&firstItem);    // ask NavServices for our first control ID
  561.                                 
  562.                         // set the command popup selection:
  563.                         realItem = firstItem + kPopupCommand;
  564.                         GetDialogItem(callBackParms->window,realItem,&itemType,&itemH,&itemRect);
  565.                         SetControlValue((ControlHandle)itemH,1);
  566.                         }
  567.                     
  568.                 // the dialog is starting up, let's override the default popup menu selection:
  569.                 UInt16 itemToSelect = kAllReadableFiles;
  570.                 theErr = NavCustomControl(callBackParms->context,kNavCtlSelectAllType,&itemToSelect);
  571.                 break;
  572.                 }
  573.                 
  574.             case kNavCBTerminate:
  575.                 // release our appended popup menu:
  576.                 if (gDitlList)
  577.                     ReleaseResource(gDitlList);        
  578.                 if (gPopupMenu)
  579.                     DisposeMenu(gPopupMenu);        
  580.                 break;
  581.             }
  582. }
  583.  
  584.  
  585. // *****************************************************************************
  586. // *
  587. // *    DoCustomOpen()
  588. // *    
  589. // *****************************************************************************
  590. void DoCustomOpen()
  591. {    
  592.     NavReplyRecord        theReply;
  593.     NavDialogOptions    dialogOptions;
  594.     OSErr                theErr = noErr;
  595.     NavTypeListHandle    typeList = NULL;
  596.     long                count = 0;
  597.     NavEventUPP            eventUPP = NewNavEventProc(myCustomEventProc);
  598.     
  599.     // default behavior for browser and dialog:
  600.     theErr = NavGetDefaultDialogOptions(&dialogOptions);
  601.  
  602.     GetIndString((unsigned char*)&dialogOptions.clientName,rAppStringsID,sApplicationName);
  603.     
  604.     typeList = (NavTypeListHandle)GetResource(kOpenRsrcType,kOpenRsrcID);
  605.     if ((typeList != NULL)&&(ResError() == noErr))
  606.         HLock((Handle)typeList);
  607.  
  608.     theErr = NavGetFile(NULL,    // use system's default location
  609.                         &theReply,
  610.                         &dialogOptions,
  611.                         eventUPP,
  612.                         NULL,    // no custom previews
  613.                         NULL,
  614.                         typeList,
  615.                         (NavCallBackUserData)&gDocumentList);
  616.  
  617.     DisposeRoutineDescriptor(eventUPP);
  618.  
  619.     if (theReply.validRecord && theErr == noErr)
  620.         {
  621.         // since we allow for multiple objects to be returned,
  622.         // grab the target FSSpecs from 'theReply.fileRef' list for opening:    
  623.         FSSpec    finalFSSpec;    
  624.         AEDesc     resultDesc;
  625.         FInfo    fileInfo;
  626.  
  627.         // we are ready to open the document(s), grab information about each file for opening:
  628.         theErr = AECountItems(&(theReply.selection),&count);
  629.         for (long index=1;index<=count;index++)
  630.             {
  631.             resultDesc.dataHandle = 0L;
  632.             theErr = AEGetNthDesc(&(theReply.selection),index,typeFSS,NULL,&resultDesc);
  633.             if (theErr == noErr)
  634.                 {
  635.                 BlockMoveData(*resultDesc.dataHandle,&finalFSSpec,sizeof(FSSpec));
  636.             
  637.                 // decide if the doc we are opening is a 'PICT' or 'TEXT':
  638.                 theErr = FSpGetFInfo(&finalFSSpec,&fileInfo);
  639.                 if (theErr == noErr)
  640.                     {
  641.                     if (fileInfo.fdType == kFileType)
  642.                         (void)DoOpenFile(&finalFSSpec,false);
  643.                     else
  644.                         if (fileInfo.fdType == kFileTypePICT)
  645.                             (void)DoOpenFile(&finalFSSpec,true);
  646.                         else
  647.                             {
  648.                             // error:
  649.                             // if we got this far, the document is a type we can't open and
  650.                             // (most likely) built-in translation was turned off.
  651.                             // You can alert the user that this returned selection or file spec
  652.                             // needs translation.
  653.                             }
  654.                     }
  655.                 theErr = AEDisposeDesc(&resultDesc);
  656.                 }
  657.             }
  658.         
  659.         theErr = NavDisposeReply(&theReply);    // clean up after ourselves    
  660.         }
  661.  
  662.     if (typeList != NULL)
  663.         {
  664.         HUnlock((Handle)typeList);
  665.         ReleaseResource((Handle)typeList);
  666.         }
  667.  
  668. }
  669.  
  670.  
  671. // *****************************************************************************
  672. // *
  673. // *    DoAbout()
  674. // *    
  675. // *****************************************************************************
  676. void DoAbout()
  677. {
  678.     GrafPtr        savePort;
  679.     DialogPtr    aboutDialog;
  680.     short        itemHit = 0;
  681.     Handle        itemH;
  682.     short        itemType;
  683.     Rect        itemRect;
  684.     
  685.     SetCursor(&qd.arrow);
  686.     aboutDialog = GetNewDialog(rAboutID,nil,(WindowRef)-1);
  687.     
  688.     GetPort(&savePort);
  689.  
  690.     SetPort((GrafPtr)aboutDialog);
  691.  
  692.     AdornButton(aboutDialog,dOK);
  693.  
  694.     GetDialogItem(aboutDialog,iIconSuite,&itemType,&itemH,&itemRect);
  695.     DrawIconSuite(rIconSuite,itemRect);
  696.                     
  697.     do ModalDialog(nil,&itemHit);
  698.  
  699.     while(itemHit != dOK);
  700.     
  701.     SetPort(savePort);
  702.     DisposeDialog(aboutDialog);
  703. }
  704.  
  705.  
  706. // *****************************************************************************
  707. // *
  708. // *    DoMenuCommand()
  709. // *
  710. // *****************************************************************************
  711. void DoMenuCommand(long select)
  712. {    
  713.     short        theMenuID, theItem;
  714.     MenuHandle    theMenu;
  715.     Str255        theName;
  716.     WindowPtr    theWindow;
  717.     Document*    theDocument = nil;
  718.     OSStatus    theErr = noErr;
  719.  
  720.     theDocument = IsDocumentWindow(theWindow = (WindowPtr)FrontWindow());
  721.  
  722.     theItem   = LoWord(select);
  723.     theMenuID = HiWord(select);
  724.     theMenu   = GetMenuHandle(theMenuID);
  725.     switch(theMenuID)
  726.         {
  727.         case idAppleMenu:
  728.             switch(theItem)
  729.                 {
  730.                 case AboutItem:
  731.                     DoAbout();
  732.                     break;
  733.                 default:
  734.                     GetMenuItemText(GetMenuHandle(idAppleMenu),theItem,(unsigned char*)&theName);
  735.                     OpenDeskAcc(theName);
  736.                 }
  737.             break;
  738.             
  739.         case idFileMenu:
  740.             switch(theItem)
  741.                 {
  742.                 case NewItem:
  743.                     DoNewDocument(false);
  744.                     AdjustMenus();
  745.                     break;
  746.                     
  747.                 case OpenItem:
  748.                     if (gNavServicesExists)
  749.                         (void)DoOpenDocument();
  750.                     else    
  751.                         (void)DoOpenDocumentTheOldWay();
  752.                     AdjustMenus();        
  753.                     break;
  754.                     
  755.                 case CloseItem:
  756.                     if (theDocument)
  757.                         {
  758.                         CloseDocument(theDocument,false);
  759.                         AdjustMenus();
  760.                         DrawMenuBar();
  761.                         }
  762.                     break;
  763.                     
  764.                 case SaveItem:
  765.                     if (theDocument)
  766.                         DoSaveDocument(theDocument);
  767.                     break;
  768.                 
  769.                 case SaveACopyItem:
  770.                     if (theDocument)
  771.                         {
  772.                         if (gNavServicesExists)
  773.                             (void)SaveACopyDocument(theDocument);
  774.                         else
  775.                             (void)SaveACopyDocumentTheOldWay(theDocument);
  776.                         }
  777.                     break;
  778.     
  779.                 case RevertItem:
  780.                     DisableUndoDrag();
  781.                     if (theDocument)
  782.                         {
  783.                         if (gNavServicesExists)
  784.                             DoRevertDocument(theDocument);
  785.                         else
  786.                             DoRevertDocumentTheOldWay(theDocument);
  787.                         }
  788.                     break;
  789.  
  790.                 case DictionaryItem:
  791.                     DoSelectDictionary();
  792.                     break;
  793.  
  794.                 case QuitItem:
  795.                     gQuitting = true;
  796.                     while ((gQuitting) && (theDocument = IsDocumentWindow((WindowPtr)FrontWindow())))
  797.                         CloseDocument(theDocument,true);
  798.                     if (gQuitting)
  799.                         gQuit = true;
  800.                     break;
  801.                 }
  802.             break;
  803.             
  804.         case idEditMenu:
  805.             switch(theItem)
  806.                 {
  807.                 case iUndo:
  808.                     DoUndoDrag();
  809.                     break;
  810.                     
  811.                 case iCut:
  812.                     if ((theDocument)&&(theDocument->theTE != NULL))
  813.                         {
  814.                         DisableUndoDrag();
  815.                         myTECut(theDocument->theTE);
  816.                         }
  817.                     break;
  818.                     
  819.                 case iCopy:
  820.                     if (theDocument)
  821.                         TECopy(theDocument->theTE);
  822.                     break;
  823.                     
  824.                 case iPaste:
  825.                     if ((theDocument)&&(theDocument->theTE != NULL))
  826.                         if (!DoPaste())
  827.                             {
  828.                             DisableUndoDrag();
  829.                             myTEPaste(theDocument->theTE,0L,0L);
  830.                             }
  831.                     break;
  832.                     
  833.                 case iClear:
  834.                     if ((theDocument)&&(theDocument->theTE != NULL))
  835.                         {
  836.                         DisableUndoDrag();
  837.                         TEDelete(theDocument->theTE);
  838.                         }
  839.                     break;
  840.                     
  841.                 case iSelectAll:
  842.                     if ((theDocument)&&(theDocument->theTE != NULL))
  843.                         DoSelectAllDocument(theDocument);
  844.                     break;
  845.                 }
  846.             break;
  847.  
  848.         case idUtilsMenu:
  849.             switch (theItem)
  850.                 {
  851.                 case iSelectDir:
  852.                     DoSelectDirectory();
  853.                     break;
  854.                 case iSelectVol:
  855.                     DoSelectVolume();
  856.                     break;
  857.                 case iSelectObject:
  858.                     DoSelectObject();
  859.                     break;
  860.                 case iCreateFolder:
  861.                     DoCreateFolder();
  862.                     break;
  863.                 case iCustomOpen:
  864.                     DoCustomOpen();
  865.                     break;
  866.                 }
  867.             break;
  868.         }        
  869.  
  870.     if (theDocument = IsDocumentWindow((WindowPtr)FrontWindow()))
  871.         if (theDocument->theTE != NULL)
  872.             TEGetHiliteRgn(theDocument->hiliteRgn,theDocument->theTE);
  873.  
  874.     HiliteMenu(0);
  875. }
  876.  
  877.